# !/usr/bin/env python

import json
import logging as logger
import os,sys
from ansible import context
from ansible.module_utils.common.collections import ImmutableDict
from common.InventoryGen import DynamicInventory
from common.ResultCallback import ADhocCallback,PlayBookCallback
from ansible.inventory.manager import InventoryManager
from ansible.vars.manager import VariableManager
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.playbook.play import Play
from ansible import constants
from ansible.plugins.callback import CallbackBase
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.executor.playbook_executor import PlaybookExecutor

class AnsibleExec():
    def   __init__(self,
             resource=None,
             connection='smart',  # Connection method: local as local access，smart as ssh
             remote_user=None,  # Remote username
             ack_pass=None,  # ackonwledge password
             sudo=None, sudo_user=None, ask_sudo_pass=None,
             module_path=None,
             become=None,  # change login user
             become_method=None,  # if sodu is involved
             become_user=None,  # change executive user
             check=False,
             diff=False,
             listhosts=None,
             listtasks=None,
             listtags=None,
             verbosity=3,
             syntax=None,
             start_at_task=None,
             inventory=None):

        context.CLIARGS = ImmutableDict(
            connection=connection,
            remote_user=remote_user,
            ack_pass=ack_pass,
            sudo=sudo,
            sudo_user=sudo_user,
            ask_sudo_pass=ask_sudo_pass,
            module_path=module_path,
            become=become,
            become_method=become_method,
            become_user=become_user,
            verbosity=verbosity,
            listhosts=listhosts,
            listtasks=listtasks,
            listtags=listtags,
            syntax=syntax,
            start_at_task=start_at_task,
        )
        self.resource = resource
        self.loader = DataLoader()
        self.passwords = dict()
        # self.inventory = InventoryManager(loader=self.loader, sources=['/etc/ansible/inventory/hosts'])
        # self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)
        if self.resource:
            dynamicinventory = DynamicInventory(self.resource)
            self.variable_manager = dynamicinventory.variable_manager
            self.inventory = dynamicinventory.inventory

    def runansible(self, host_list, task_list):
        self.results_callback = PlayBookCallback()
        play_source = dict(
            name="Get IMT information",
            hosts=host_list,  # 传入hosts分组或main_ip
            gather_facts="no",
            tasks=task_list
        )
        # play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)
        play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)
        tqm = None
        try:
            tqm = TaskQueueManager(
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                passwords=self.passwords,
                stdout_callback=self.results_callback
            )
            result = tqm.run(play)
            # tqm._stdout_callback = self.results_callback
            constants.HOST_KEY_CHECKING = False
            self.results_raw = self.results_callback.result_row
            print (self.results_callback.result_row)
        except Exception as err:
            print(err)
        finally:
            if tqm is not None:
                tqm.cleanup()

    def run_playbook(self, playbookpath):
        # print('playbook Host参数:%s' % self.inventory.get_groups_dict() + "================")
        # host = self.inventory.get_host(hostname='localhost')
        # print('playbook vars参数:%s' % self.inventory.get_vars(host=host)+ "=======**=======")
        self.results_callback = PlayBookCallback()
        try:
            # self.variable_manager.extra_vars = extra_vars
            playbook = PlaybookExecutor(
                playbooks=[playbookpath],
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                passwords=self.passwords,
            )
            playbook._tqm._stdout_callback = self.results_callback
            playbook.run()
            self.results_raw = self.results_callback.result_row
            return self.results_callback.result_row

        except Exception as err:
            print (err)
            return err
